package com.example.module.widget;

import java.lang.reflect.Method;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.example.R;
import com.example.module.web.CustomAddressBar;
import com.example.util.SharedPreferenceUtil;

public class CustomBrowser extends LinearLayout {
	private static final String LOG_TAG = "CustomBrowser";

	private static final int SCROLL_BY = 3;
	
	private CustomAddressBar addressBar;
	private ImageView bookmarkButton;
	
	private FrameLayout webViewBox;
	private WebView webView;
	private FrameLayout webViewOverlay;
	
	private String currentUrl;
	private boolean isExpanded;
	public boolean isAnimationFinished;
	
	float prevEventY;
	int scrollTo = 0;
	boolean isForward, isHold;
	boolean useEmbeddedTitleBar;
	
	private BrowserActionListener browserActionListener;

	public interface BrowserActionListener {
		public void onBookmarkCheck(String url);
		public void onBookmarkClick();
		public void onOverlayClick();
	}

	public CustomBrowser(Context context) {
		super(context);
		initialize(context);
	}
	public CustomBrowser(Context context, AttributeSet attrs) {
		super(context, attrs);
		initialize(context);
	}

	private void initialize(Context context) {
		LayoutInflater.from(context).inflate(R.layout.web_browser, this, true);
		webViewBox = (FrameLayout) findViewById(R.id.webViewBox);
		webViewOverlay = (FrameLayout) findViewById(R.id.webViewOverlay);
		webViewOverlay.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View view) {
				if (browserActionListener != null)
					browserActionListener.onOverlayClick();
			}
		});

		// setup WebView
		webView = (WebView) findViewById(R.id.webView);
        webView.setWebViewClient(new WebViewClient(){
	    	@Override
	    	public void onPageStarted(WebView view, String url, Bitmap favicon) {
	    		addressBar.setAddressUrl(url);
	    		currentUrl = url;
	    		webView.requestFocus();
	    		scrollTo(0, 0);
	    		
	    		if (browserActionListener != null)
	    			browserActionListener.onBookmarkCheck(url);
	    		
	    		super.onPageStarted(view, url, favicon);
	    	}
	    	
	    	@Override
	    	public void onPageFinished(WebView view, String url) {
	    		SharedPreferenceUtil.putString(getContext(), "currentUrl", currentUrl);
	    		super.onPageFinished(view, url);
	    	}
        });
		
		webView.setWebChromeClient(new WebChromeClient() {
        	@Override
        	public void onProgressChanged(WebView view, int newProgress) {
        		super.onProgressChanged(view, newProgress);
        		addressBar.changeAddressProgress(newProgress);
        	}
        });
		
		addressBar = new CustomAddressBar(context);
		try {
			useEmbeddedTitleBar = true;
			Method method = WebView.class.getMethod("setEmbeddedTitleBar", new Class[] { View.class });
			method.invoke(webView, addressBar);
		}
		catch (Exception e) {
			e.printStackTrace();

			useEmbeddedTitleBar = false;
			addView(addressBar, 0);
			
			/*
			webView.setScrollListener(new CustomWebView.ScrollListener() {
				
				@Override
				public void onScrollBy(final int distance) {
					post(new Runnable() {
						
						@Override
						public void run() {
							int scrollBy = distance * -1;
							scrollBy += SCROLL_BY;
							while (scrollBy < 0) {
								Log.w(LOG_TAG, "scrollBrowser scrollBy=" + scrollBy);
								scrollBy(0, scrollBy);
								if (getScrollY() <= 0) {
									scrollTo(0, 0);
									return;
								}
								
								scrollBy += SCROLL_BY;
							}
						}
					});
				}

				@Override
				public void onScrollTo(int distance) {
					// 위로 올릴 경우
					final int scrollY = getScrollY();
					if (scrollY > 0) {
						int scrollTo = scrollY - distance;
						if (scrollTo < 0)
							scrollTo = 0;
						
						Log.w(LOG_TAG, "scrollBrowser scrollTo=" + scrollTo);
						scrollTo(0, scrollTo);
					}
				}
			});
			*/
		}
		
		addressBar.setWebViewListener(new CustomAddressBar.WebViewListener() {
			@Override
			public void onLoad(String url) {
				webView.loadUrl(url);
			}
			
			@Override
			public void onLoadFinished() {
				// TODO Auto-generated method stub
				
			}
		});
		
		bookmarkButton = addressBar.getBookmarkButton();
		bookmarkButton.setOnClickListener(new View.OnClickListener() {
 			@Override
 			public void onClick(View v) {
 				if (browserActionListener != null)
 					browserActionListener.onBookmarkClick();
 			}
 		});
	}
	
	public WebView getWebView() {
		return webView;
	}
	public void setWebView(CustomWebView webView) {
		this.webView = webView;
	}
	
	public FrameLayout getWebViewBox() {
		return webViewBox;
	}
	public void setWebViewBox(FrameLayout webViewBox) {
		this.webViewBox = webViewBox;
	}
	
	public BrowserActionListener getBrowserActionListener() {
		return browserActionListener;
	}
	public void setBrowserActionListener(BrowserActionListener browserActionListener) {
		this.browserActionListener = browserActionListener;
	}
	
	public String getCurrentUrl() {
		return currentUrl;
	}
	public void setCurrentUrl(String currentUrl) {
		this.currentUrl = currentUrl;
	}
	
	public void loadUrl(String url) {
		webView.loadUrl(url);
	}
	
	public void displayOverlay(boolean value) {
		webViewOverlay.setAnimation(AnimationUtils.loadAnimation(getContext(), value ? R.anim.fade_in : R.anim.fade_out));
		webViewOverlay.setVisibility(value ? View.VISIBLE : View.GONE);
		
		Log.d("displayOverlay", "value=" + value + " overlay.getVisibility()=" + webViewOverlay.getVisibility());
	}
	
	public void animateBookmarkShot(Bitmap bitmap) {
		final Snapshot snapshot = new Snapshot(getContext());
		snapshot.setBackgroundDrawable(new BitmapDrawable(bitmap));
		webViewBox.addView(snapshot);
		snapshot.animateSpin(new Animation.AnimationListener() {
			
			@Override
			public void onAnimationStart(Animation animation) {
				isAnimationFinished = false;
				Log.e("animateBookmarkShot", "onAnimationStart");
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				isAnimationFinished = true;
				Log.e("animateBookmarkShot", "onAnimationEnd");
				webViewBox.removeView(snapshot);
			}
		});
	}
	
	public void animateCaptureShot() {
		final Snapshot snapshot = new Snapshot(getContext());
		Drawable drawable = getResources().getDrawable(R.drawable.wind);
		drawable.setAlpha(190);
		snapshot.setBackgroundDrawable(drawable);
		
		webViewBox.addView(snapshot);
		snapshot.animateFade(new Animation.AnimationListener() {
			
			@Override
			public void onAnimationStart(Animation animation) {
				isAnimationFinished = false;
				Log.e("animateCaptureShot", "onAnimationStart");
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				Animation nextAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.flash);
				nextAnimation.setAnimationListener(new Animation.AnimationListener() {

					@Override
					public void onAnimationStart(Animation animation) {}

					@Override
					public void onAnimationRepeat(Animation animation) {}
					
					@Override
					public void onAnimationEnd(Animation animation) {
						isAnimationFinished = true;
					}
				});
				webView.startAnimation(nextAnimation);
				
				Log.e("animateCaptureShot", "onAnimationEnd");
				webViewBox.removeView(snapshot);
			}
		});
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		if (!useEmbeddedTitleBar) {
			final int action = ev.getAction();
			final float eventY = ev.getY();
			final int motionY = Math.abs((int) (eventY - prevEventY));
			final int scrollY = getScrollY();
			final int addressBarHeight = addressBar.getHeight();
			
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				isHold = false;
				Log.w(LOG_TAG, "ACTION_DOWN motionY=" + motionY + " scrollY=" + scrollY + " scrollTo=" + scrollTo);
				break;

			case MotionEvent.ACTION_MOVE:
				isHold = true;
				isForward = eventY - prevEventY > 0 ? false : true;
				Log.w(LOG_TAG, "ACTION_MOVE isForward=" + isForward + " motionY=" + motionY + " scrollY=" + scrollY + " scrollTo=" + scrollTo);
				
				// 아래로 내릴 경우
				if (isForward) {
					if (scrollY < addressBarHeight) {
						scrollTo = scrollY + motionY;
						int distance = scrollTo - addressBarHeight;
						
						if (distance > 0) {
							scrollTo = addressBarHeight;
							Log.w(LOG_TAG, "ACTION_MOVE  scrollTo=" + scrollTo);
							scrollTo(0, scrollTo);
							
							Log.e(LOG_TAG, "ACTION_MOVE  distance=" + distance);
							scrollWebView(distance);
						}
						else {
							Log.w(LOG_TAG, "ACTION_MOVE  scrollTo=" + scrollTo);
							scrollTo(0, scrollTo);
						}
					}
				}
				
				break;
				
			case MotionEvent.ACTION_UP:
				isHold = false;
				Log.w(LOG_TAG, "ACTION_UP motionY=" + motionY + " scrollY=" + scrollY + " scrollTo=" + scrollTo);
				break;
				
			default:
				break;
			}
			
			prevEventY = eventY;
		}
		
		return super.dispatchTouchEvent(ev);
	}
	
	public void scrollWebView(final int distance) {
		
		webView.post(new Runnable() {
			
			@Override
			public void run() {
				int scrollBy = distance;
				scrollBy -= SCROLL_BY;
				while (scrollBy > 0) {
					Log.w(LOG_TAG, "scrollWebView scrollBy=" + scrollBy);
					webView.scrollBy(0, scrollBy);
					scrollBy -= SCROLL_BY;
				}
			}
		});
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		if (!useEmbeddedTitleBar) {
			if (!isExpanded && webViewBox.getWidth() > 0 && webView.getWidth() > 0) {
				expendWebView();
				isExpanded = true;
			}	
		}
		
		super.onDraw(canvas);
	}
	
	public void expendWebView() {
		ViewGroup.LayoutParams parentParams = webViewBox.getLayoutParams(); 
		parentParams.height = webViewBox.getHeight() + addressBar.getHeight();
		webViewBox.setLayoutParams(parentParams);
		
		ViewGroup.LayoutParams params = webView.getLayoutParams();
		params.height = webView.getHeight() + addressBar.getHeight();
		webView.setLayoutParams(params);
	}
	
	public void activateBookmark(boolean flag) {
		if (flag)
			bookmarkButton.setImageDrawable(getResources().getDrawable(R.drawable.star_on));
		else
			bookmarkButton.setImageDrawable(getResources().getDrawable(R.drawable.star_off));
		
		bookmarkButton.setSelected(flag);
	}
}
